package com.CST.service.impl;

import com.CST.common.api.Response;
import com.CST.common.api.ResultObject;
import com.CST.common.constant.Constants;
import com.CST.entity.BdDepartment;
import com.CST.entity.BdOrganization;
import com.CST.entity.BdOrganizationRule;
import com.CST.mapper.dataplatform.BdOrganizationMapper;
import com.CST.service.IBdDepartmentService;
import com.CST.service.IBdEnumdetailService;
import com.CST.service.IBdOrganizationService;
import com.CST.util.ExcelTransfer;
import com.CST.util.HttpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>科室部门对应 服务实现类</p>
 *
 * @author: y
 * @create: 2021-10-22 14:38
 **/
@Service
public class BdOrganizationServiceImpl extends ServiceImpl<BdOrganizationMapper, BdOrganization> implements IBdOrganizationService {

    @Autowired
    private IBdDepartmentService departmentService;


    @Autowired
    private IBdEnumdetailService bdEnumdetailService;

    @Autowired
    private IBdOrganizationService targetService;
    @Autowired
    private ExcelTransfer<BdOrganization> excelTransfer;

    @Override
    public List<BdOrganization> getOrganizationSource(BdOrganization entity) {
        List<BdOrganization> resultList = new ArrayList<>();
        //子级科室
        List<BdOrganization> organizationDBList = baseMapper.getOrganizationSource(entity);
        //父级科室
        List<BdOrganization> organizationSourceParent = baseMapper.listNoBdOrganization();
        List<BdOrganization> noRelationDepartmentList = getNoRelationDepartmentList(entity);
        resultList.addAll(organizationSourceParent);
        resultList.addAll(organizationDBList);
//        resultList.addAll(organizationSourceParent);
        return resultList;
    }

    @Override
    public List<BdOrganization> getOrganizationNormal(BdOrganization entity) {
        return baseMapper.getOrganizationNormal(entity);
    }

    @Override
    public List<BdOrganization> getNoRelationDepartmentList(BdOrganization entity) {
        List<BdOrganization> resultList = new ArrayList<>();
        BdOrganization searchOrgInfo = new BdOrganization();
        searchOrgInfo.setRuleCode(entity.getRuleCode());
        List<BdOrganization> organizationRuleCodeList = baseMapper.getOrganizationSource(searchOrgInfo);
        BdDepartment searchInfo = new BdDepartment();
        searchInfo.setProjectId(entity.getYard());
        searchInfo.setSysId("Cost");
//        searchInfo.setParentCode("0");
        searchInfo.setRowStatus("0");
        List<BdDepartment> departmentList = departmentService.getDepartmentSource(searchInfo);
        List<String> organizationCodeList = organizationRuleCodeList.stream().map(BdOrganization::getDeptCode).collect(Collectors.toList());
        departmentList.forEach(item -> {
            if (organizationCodeList.contains(item.getDeptCode())) {
                return;
            }
            BdOrganization newInfo = new BdOrganization();
            newInfo.setDeptCode(item.getDeptCode());
            newInfo.setDeptName(item.getDeptName());
            newInfo.setPDeptName("");
            newInfo.setPDeptName("");
            newInfo.setRuleCode("0");
            newInfo.setYard(item.getProjectId());
            newInfo.setRowStatus("1");
            resultList.add(newInfo);
        });
           return baseMapper.listNoBdOrganization();
    }

    @Override
    public Boolean isHaveOrganization(BdOrganization entity) {
        List<BdOrganization> result =baseMapper.isHaveOrganization(entity);
        return CollectionUtils.isNotEmpty(result);
    }

    @Override
    public Response addOrganization(BdOrganization entity) {
        try {
            Date currDate = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:hh:ss");
            entity.setCreatedOn(sdf.format(currDate));
            entity.setUpdatedOn(sdf.format(currDate));
            String userName = HttpUtil.getRequestHeaderInfo(Constants.USER_NAME);
            userName = userName == null || userName.isEmpty() ? "System" : userName;
            entity.setCreatedBy(userName);
            entity.setUpdatedBy(userName);
            baseMapper.addOrganization(entity);
        } catch (Exception ex) {
            return Response.error(String.join(":", "添加失败:", ex.getMessage()));
        }
        return Response.success("添加成功");
    }

    @Override
    public Response modifyOrganization(BdOrganization entity) {
        if (entity.getId() == 0) {
            return Response.error("主键不能为空");
        }
        try {
            Date currDate = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:hh:ss");
            entity.setCreatedOn(sdf.format(currDate));
            entity.setUpdatedOn(sdf.format(currDate));
            String userName = HttpUtil.getRequestHeaderInfo(Constants.USER_NAME);
            userName = userName == null || userName.isEmpty() ? "System" : userName;
            entity.setCreatedBy(userName);
            entity.setUpdatedBy(userName);
            baseMapper.modifyOrganization(entity);
        } catch (Exception ex) {
            return Response.error(String.join(":", "修改失败", ex.getMessage()));
        }
        return Response.success("修改成功");
    }

    @Override
    public Response batchDeleteOrganization(List<Integer> ids) {
        try {
            baseMapper.batchDeleteOrganization(ids);
        }
        catch (Exception ex)
        {
            return Response.error("删除失败");
        }
        return Response.success("删除成功");
    }

    /**
     * 添加继承关系
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Response addInheritanceRules(BdOrganizationRule entity) {
        // 获取当前ruleCode
        String ruleCode = entity.getRuleCode();
        // 先删除当前的ruleCode的数据 避免重复添加
        LambdaQueryWrapper<BdOrganization> deleteQueryWrapper = new LambdaQueryWrapper<>();
        deleteQueryWrapper.eq(BdOrganization::getRuleCode, entity.getRuleCode());
        baseMapper.delete(deleteQueryWrapper);
        // 获取指定 父类ruleCode 所有数据
        LambdaQueryWrapper<BdOrganization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BdOrganization::getRuleCode, entity.getParentRuleCode());
        List<BdOrganization> bdOrganizationList = baseMapper.selectList(queryWrapper);
        // 复制父类数据 将其中的ruleCode改成当前的ruleCode
        for (BdOrganization bdOrganization : bdOrganizationList){
            bdOrganization.setRuleCode(ruleCode);
        }
        // 将复制的ruleCode添加到表中
        // 创建一个插入缓存 tips:大量插入数据会导致数据库报错
        List<BdOrganization> cache = new ArrayList<>();
        for (int i = 0;i < bdOrganizationList.size();i ++){
            cache.add(bdOrganizationList.get(i));
            if (i != 0 || (i + 1) % 20 == 0){
                int insert = baseMapper.addOrganizationWithList(cache);
                if (insert == 0){
                    return Response.error("继承失败");
                }
                cache.clear();
            }
        }
        int i = baseMapper.addOrganizationWithList(cache);
        cache.clear();
        if (i == 0){
            return Response.error("继承失败");
        }
        return Response.success("继承成功");
    }

    @Override
    public ResultObject listParentDeptGroup(String yard) {
        
        return null;
    }

    @Override
    public List<BdOrganization> listClinicalPDeptGroup() {
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteRule(Integer edId, String ruleCode) {
        //先删除规则表,再删除对应的关系记录
        try {
            List<Integer> ids =new ArrayList<>();
            ids.add(edId);
            bdEnumdetailService.batchDeleteEnumDetail(ids);
            LambdaQueryWrapper<BdOrganization> deleteQueryWrapper = new LambdaQueryWrapper<>();
            deleteQueryWrapper.eq(BdOrganization::getRuleCode, ruleCode);
            baseMapper.delete(deleteQueryWrapper);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    @Override
    public void exportExcel(HttpServletResponse response, BdOrganization dto) throws ClassNotFoundException {
            List<BdOrganization> result = targetService.getOrganizationSource(dto);
            List<BdOrganization> collect = result.stream().filter(t -> "0".equals(t.getRowStatus())).collect(Collectors.toList());
            excelTransfer.exportExcel(response, collect, "科室部门对应", "sheet", this);
    }
}
